package com.tianqi.modules.pms.service.impl;

import cn.hutool.core.date.DateUtil;
import com.nlf.calendar.*;
import com.nlf.calendar.eightchar.DaYun;
import com.nlf.calendar.eightchar.LiuNian;
import com.nlf.calendar.eightchar.XiaoYun;
import com.nlf.calendar.eightchar.Yun;
import com.tianqi.common.api.CommonResult;
import com.tianqi.common.enums.EightCharItemEnum;
import com.tianqi.common.enums.FulInitialsBeloEnum;
import com.tianqi.common.enums.GenderTypeEnum;
import com.tianqi.common.utils.LunarDateUtil;
import com.tianqi.modules.pms.dto.request.ArrangeDiskReqDTO;
import com.tianqi.modules.pms.dto.response.*;
import com.tianqi.modules.pms.service.TianganDizhiService;
import com.tianqi.modules.tqs.constant.RelationMapConstant;
import com.tianqi.modules.tqs.service.TqCoreDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @className: TianganDizhiServiceImpl
 * @description: 天干地支实现类
 * @author: zp
 * @create: 2023-08-07 09:21
 **/
@Service
@Slf4j
public class TianganDizhiServiceImpl implements TianganDizhiService {
    @Autowired
    private TqCoreDataService tqCoreDataService;

    @Autowired
    private LunarDateUtil lunarDateUtil;

    @Override
    public CommonResult<EightCharAllRespDTO> getEightCharacters(ArrangeDiskReqDTO arrangeDiskReq) {
        // 当前时间
        long startMillis = System.currentTimeMillis();
        // 总出参
        EightCharAllRespDTO eightCharAllRespDTO = new EightCharAllRespDTO();
        if (arrangeDiskReq.getGenderType() == null) {
            return CommonResult.failed("性别不能为空");
        }
        if (!arrangeDiskReq.getGenderType().equals(GenderTypeEnum.MALE.getCode())
                && !arrangeDiskReq.getGenderType().equals(GenderTypeEnum.FEMALE.getCode())) {
            return CommonResult.failed("性别不正确");
        }
        // 转换生辰八字
        Lunar birthLunar = lunarDateUtil.formatEightChar(arrangeDiskReq.getBirthDay());
        // 阳历生日时间
        Solar birthSolar = birthLunar.getSolar();
        EightChar birthEightChar = birthLunar.getEightChar();
        // 设置流派1
        birthEightChar.setSect(1);
        // 获取八字日干
        String dayGan = birthEightChar.getDayGan();
        // 转换占时八字
        Lunar divineLunar = lunarDateUtil.formatEightChar((arrangeDiskReq.getDivineDay()));
        EightChar divineEightChar = divineLunar.getEightChar();
        // 设置流派1
        divineEightChar.setSect(1);
        // 设置占时的八字
        NowEightCharResp divineNowEightCharResp = new NowEightCharResp();
        setEightCharInfo(divineLunar, divineNowEightCharResp);
        eightCharAllRespDTO.setDivineEightChar(divineNowEightCharResp);
        // 起运
        Yun yun = birthEightChar.getYun(arrangeDiskReq.getGenderType(), 2);
        // 设置起运时间
        eightCharAllRespDTO.setQiYunStartYear(yun.getStartYear());
        eightCharAllRespDTO.setQiYunStartMonth(yun.getStartMonth());
        eightCharAllRespDTO.setQiYunStartDay(yun.getStartDay());
        eightCharAllRespDTO.setQiYunStartHour(yun.getStartHour());
        // 设置六个柱
        List<EightCharItemDTO> eightCharItemList = new ArrayList<>(6);
        // 流年
        EightCharItemDTO fleetingYearColumn = new EightCharItemDTO();
        fleetingYearColumn.setType(EightCharItemEnum.LIUNIAN);
        formatZhu(birthEightChar, yun, fleetingYearColumn);
        eightCharItemList.add(fleetingYearColumn);
        // 大运
        EightCharItemDTO bigLuckColumn = new EightCharItemDTO();
        bigLuckColumn.setType(EightCharItemEnum.DAYUN);
        formatZhu(birthEightChar, yun, bigLuckColumn);
        eightCharItemList.add(bigLuckColumn);
        // 年干支
        EightCharItemDTO yearInGanZhiColumn = new EightCharItemDTO();
        yearInGanZhiColumn.setType(EightCharItemEnum.YEAR);
        formatZhu(birthEightChar, yun, yearInGanZhiColumn);
        eightCharItemList.add(yearInGanZhiColumn);
        // 月干支
        EightCharItemDTO monthInGanZhiColumn = new EightCharItemDTO();
        monthInGanZhiColumn.setType(EightCharItemEnum.MONTH);
        formatZhu(birthEightChar, yun, monthInGanZhiColumn);
        eightCharItemList.add(monthInGanZhiColumn);
        // 日干支
        EightCharItemDTO dayInGanZhiColumn = new EightCharItemDTO();
        dayInGanZhiColumn.setType(EightCharItemEnum.DAY);
        formatZhu(birthEightChar, yun, dayInGanZhiColumn);
        eightCharItemList.add(dayInGanZhiColumn);
        // 时干支
        EightCharItemDTO timeInGanZhiColumn = new EightCharItemDTO();
        timeInGanZhiColumn.setType(EightCharItemEnum.TIME);
        formatZhu(birthEightChar, yun, timeInGanZhiColumn);
        eightCharItemList.add(timeInGanZhiColumn);
        eightCharAllRespDTO.setEightCharItemList(eightCharItemList);
        // 获取大运列表数组
        DaYun[] daYuns = yun.getDaYun();
        // 计算起运在什么节气后多少天
        Solar next = birthSolar.nextYear(yun.getStartYear())
                .nextMonth(yun.getStartMonth())
                .next(yun.getStartDay())
                .nextHour(yun.getStartHour());
        JieQi jiaoYunPreJieqi = next.getLunar().getPrevJieQi();
        int jiaoYunPreJieqiDay = next.subtract(jiaoYunPreJieqi.getSolar());
        eightCharAllRespDTO.setJiaoYunJieQiDay(jiaoYunPreJieqi.getName() + "后" + jiaoYunPreJieqiDay + "天");
        // 获取第一个大运中的流年
        LiuNian[] liuNianOne = daYuns[1].getLiuNian();
        // 获取第一个流年的干支
        eightCharAllRespDTO.setJiaoYunTian(liuNianOne[0].getGanZhi().charAt(0) + "、" +
                RelationMapConstant.FIND_WUHE_TIANGAN.get(liuNianOne[0].getGanZhi().substring(0, 1)));
        // 计算年龄
        int age = DateUtil.year(DateUtil.date()) - birthLunar.getSolar().getYear() + 1;
        eightCharAllRespDTO.setAge(age);
        // 计算司令
        String siLing = getSiMingByEightChar(birthLunar);
        eightCharAllRespDTO.setSiLing(siLing);
        eightCharAllRespDTO.setTaiYuan(birthEightChar.getTaiYuan() + formatNaYinChar(birthEightChar.getTaiYuan()));
        eightCharAllRespDTO.setTaiXi(birthEightChar.getTaiXi() + formatNaYinChar(birthEightChar.getTaiXi()));
        eightCharAllRespDTO.setShenGong(birthEightChar.getShenGong() + formatNaYinChar(birthEightChar.getShenGong()));
        eightCharAllRespDTO.setMingGong(birthEightChar.getMingGong() + formatNaYinChar(birthEightChar.getMingGong()));
        // 计算命卦
        String mingGua = getMingGuaByBirth(birthLunar, arrangeDiskReq.getGenderType());
        eightCharAllRespDTO.setMingGua(mingGua);
        eightCharAllRespDTO.setXingXiu(birthLunar.getXiu() +
                "宿" + RelationMapConstant.XING_XIU_FANG_WEI.get(birthLunar.getXiu()));
        // 结束时间
        long endMillis = System.currentTimeMillis();
        log.info("接口耗时:{}", endMillis - startMillis);
        return CommonResult.success(eightCharAllRespDTO);
    }

    /**
     * 根据日期获取八字-大运部分
     *
     * @param arrangeDiskReq
     * @return
     */
    @Override
    public CommonResult<EightCharPartRespDTO> getEightCharPart(ArrangeDiskReqDTO arrangeDiskReq) {
        // 当前时间
        long startMillis = System.currentTimeMillis();
        // 总出参
        EightCharPartRespDTO eightCharPartRespDTO = new EightCharPartRespDTO();
        if (arrangeDiskReq.getGenderType() == null) {
            return CommonResult.failed("性别不能为空");
        }
        if (!arrangeDiskReq.getGenderType().equals(GenderTypeEnum.MALE.getCode())
                && !arrangeDiskReq.getGenderType().equals(GenderTypeEnum.FEMALE.getCode())) {
            return CommonResult.failed("性别不正确");
        }
        // 转换生辰八字
        Lunar birthLunar = lunarDateUtil.formatEightChar(arrangeDiskReq.getBirthDay());
        // 阳历生日时间
        Solar birthSolar = birthLunar.getSolar();
        EightChar birthEightChar = birthLunar.getEightChar();
        // 设置流派1
        birthEightChar.setSect(1);
        // 获取八字日干
        String dayGan = birthEightChar.getDayGan();
        // 起运
        Yun yun = birthEightChar.getYun(arrangeDiskReq.getGenderType(), 2);
        // 获取大运列表数组
        DaYun[] daYuns = yun.getDaYun();
        // 设置大运
        List<DaYunDto> daYunDtoList = new ArrayList<>();
        for (int i = 0; i < daYuns.length; i++) {
            DaYunDto daYunDto = new DaYunDto();
            DaYun daYun = daYuns[i];

            // 设置小运
            List<XiaoYunDto> xiaoYunDtoList = new ArrayList<>();
            XiaoYun[] xiaoYunZeroList = daYun.getXiaoYun();
            Arrays.asList(xiaoYunZeroList).forEach(xiaoYunZero -> {
                XiaoYunDto xiaoYunDto = new XiaoYunDto();
                xiaoYunDto.setIndex(xiaoYunZero.getIndex());
                xiaoYunDto.setGanZhi(xiaoYunZero.getGanZhi());
                xiaoYunDtoList.add(xiaoYunDto);
            });
            daYunDto.setXiaoYunList(xiaoYunDtoList);
            //设置流年
            List<LiuNianDto> liuNianDtoList = new ArrayList<>();
            Arrays.asList(daYun.getLiuNian()).forEach(liuNian -> {
                LiuNianDto liuNianDto = new LiuNianDto();
                liuNianDto.setIndex(liuNian.getIndex());
                liuNianDto.setYear(liuNian.getYear());
                liuNianDto.setAge(liuNian.getAge());
                liuNianDto.setGanZhi(liuNian.getGanZhi());
                liuNianDto.setGanShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                        RelationMapConstant.TIANGAN_TIANGANSHISHEN_MAP.get(dayGan + liuNian.getGanZhi().charAt(0))).getAbbreviation());
                liuNianDto.setZhiShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                        RelationMapConstant.TIANGAN_DIZHISHISHEN_MAP.get(dayGan + liuNian.getGanZhi().charAt(1))).getAbbreviation());
                // 获取流年年份，初始化农历时间
                Lunar liuNianLunar = Lunar.fromYmd(liuNian.getYear(), 1, 1);
                // 获取当年节气列表
                Map<String, Solar> jieQiTable = liuNianLunar.getJieQiTable();
                // 设置流月
                List<LiuYueDto> liuYueDtoList = new ArrayList<>();
                Arrays.asList(liuNian.getLiuYue()).forEach(liuYue -> {
                    LiuYueDto liuYueDto = new LiuYueDto();
                    liuYueDto.setIndex(liuYue.getIndex());
                    // 根据干支转换为节气
                    switch (liuYue.getGanZhi().substring(1, 2)) {
                        case "寅": {
                            liuYueDto.setJieQi("立春");
                            break;
                        }
                        case "卯": {
                            liuYueDto.setJieQi("惊蛰");
                            break;
                        }
                        case "辰": {
                            liuYueDto.setJieQi("清明");
                            break;
                        }
                        case "巳": {
                            liuYueDto.setJieQi("立夏");
                            break;
                        }
                        case "午": {
                            liuYueDto.setJieQi("芒种");
                            break;
                        }
                        case "未": {
                            liuYueDto.setJieQi("小暑");
                            break;
                        }
                        case "申": {
                            liuYueDto.setJieQi("立秋");
                            break;
                        }
                        case "酉": {
                            liuYueDto.setJieQi("白露");
                            break;
                        }
                        case "戌": {
                            liuYueDto.setJieQi("寒露");
                            break;
                        }
                        case "亥": {
                            liuYueDto.setJieQi("立冬");
                            break;
                        }
                        case "子": {
                            liuYueDto.setJieQi("大雪");
                            break;
                        }
                        case "丑": {
                            liuYueDto.setJieQi("XIAO_HAN");
                            break;
                        }
                        default:
                            break;
                    }
                    // 查询节气的月份
                    liuYueDto.setJieQiMonth(jieQiTable.get(liuYueDto.getJieQi()).getMonth());
                    liuYueDto.setJieQiDay(jieQiTable.get(liuYueDto.getJieQi()).getDay());
                    if ("XIAO_HAN".equals(liuYueDto.getJieQi())) {
                        liuYueDto.setJieQi("小寒");
                    }
                    liuYueDto.setGanZhi(liuYue.getGanZhi());
                    liuYueDto.setGanShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                            RelationMapConstant.TIANGAN_TIANGANSHISHEN_MAP.get(dayGan + liuYue.getGanZhi().charAt(0))).getAbbreviation());
                    liuYueDto.setZhiShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                            RelationMapConstant.TIANGAN_DIZHISHISHEN_MAP.get(dayGan + liuYue.getGanZhi().charAt(1))).getAbbreviation());
                    liuYueDtoList.add(liuYueDto);
                });
                liuNianDto.setLiuYueList(liuYueDtoList);
                liuNianDtoList.add(liuNianDto);
            });
            daYunDto.setLiuNianList(liuNianDtoList);
            // 判断是不是第一个，不是大运
            if (i == 0) {
                daYunDto.setIndex(daYun.getIndex());
                daYunDto.setYear(daYun.getStartYear());
                daYunDto.setAge(daYun.getEndAge());
                daYunDtoList.add(daYunDto);
                continue;
            }
            daYunDto.setIndex(daYun.getIndex());
            daYunDto.setGanZhi(daYun.getGanZhi());
            daYunDto.setAge(daYun.getStartAge());
            daYunDto.setYear(daYun.getStartYear());
            daYunDto.setGanShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                    RelationMapConstant.TIANGAN_TIANGANSHISHEN_MAP.get(dayGan + daYun.getGanZhi().charAt(0))).getAbbreviation());
            daYunDto.setZhiShiShen(FulInitialsBeloEnum.getValueByelEment("十神",
                    RelationMapConstant.TIANGAN_DIZHISHISHEN_MAP.get(dayGan + daYun.getGanZhi().charAt(1))).getAbbreviation());
            daYunDtoList.add(daYunDto);
        }
        eightCharPartRespDTO.setDaYunList(daYunDtoList);
        // 结束时间
        long endMillis = System.currentTimeMillis();
        log.info("接口耗时:{}", endMillis - startMillis);
        return CommonResult.success(eightCharPartRespDTO);
    }

    @Override
    public CommonResult<CalendarNowDayDTO> getCalendarDays(String yearMonth){
        try{
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = format.parse(yearMonth);
            CalendarNowDayDTO resultData=new CalendarNowDayDTO();
            //日期实例化
            Solar solar = Solar.fromDate(date);
            //当年一月一日 转阴历
            Lunar lunarJieqi = solar.getLunar();
            Map<String, Solar> jieqi=lunarJieqi.getJieQiTable();
            List<String> jieqiResult=new ArrayList<>();
            //当月节气赋值
            jieqi.forEach((k,v)->{
                if(v.toYmdHms().startsWith(solar.getYear()+"-"+(String.valueOf(solar.getMonth()).length()==1?"0"+solar.getMonth():solar.getMonth()))){
                    try {
                        Date dateJieqi=format.parse(v.toYmdHms());
                        SimpleDateFormat formatJieqi = new SimpleDateFormat("MM月dd日HH:mm");
                        jieqiResult.add(k+"："+formatJieqi.format(dateJieqi));
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }

                }
            });
            resultData.setJieQi(jieqiResult);
            //计算万年历
            SolarMonth month= SolarMonth.fromDate(date);
            List<Solar> days = month.getDays();
            List<CalendarDaysDTO> data = new ArrayList<>();
            days.forEach((e)->{
                Lunar lunar =e.getLunar();
                //获取八字
                EightChar eightChar=lunar.getEightChar();
                // 设置流派1
                eightChar.setSect(1);
                //节日
                List<String> festivals=new ArrayList<>();
                festivals.addAll(e.getFestivals());
                festivals.addAll(lunar.getFestivals());
                CalendarDaysDTO day=new CalendarDaysDTO()
                        .setCurrentJie(lunar.getCurrentJieQi()!=null?lunar.getCurrentJieQi().getName():"")
                        .setFestivals(festivals)
                        .setWeek(e.getWeekInChinese())
                        .setSolarYear(e.getYear())
                        .setSolarMonth(e.getMonth())
                        .setSolarday(e.getDay())
                        .setLunarYear(lunar.getYearInChinese())
                        .setLunarMonth(lunar.getMonthInChinese())
                        .setLunarday(lunar.getDayInChinese())
                        .setDayGanZhi(eightChar.getDay())
                        .setIsSelected(e.getDay()==solar.getDay()?true:false)
                        ;
                data.add(day);
            });
            resultData.setCalendarDays(data);
            //计算查询公立时间的信息
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
            String gongLi = formatter.format(date);
            resultData.setGongLi("公历："+gongLi);
            //计算查询农历
            Lunar lunarQuery=solar.getLunar();
            //获取八字
            EightChar eightCharQuery=lunarQuery.getEightChar();
            // 设置流派1
            eightCharQuery.setSect(1);
            resultData.setNongLi("农历："+eightCharQuery.getYear()+"年"+lunarQuery.getMonthInChinese()+"月"+lunarQuery.getDayInChinese()+"日 "+eightCharQuery.getTimeZhi()+"时");
            resultData.setGanZhi("干支："+eightCharQuery.getYear()+" "+eightCharQuery.getMonth()+" "+eightCharQuery.getDay()+" "+eightCharQuery.getTime()+"（年空："+eightCharQuery.getYearXunKong()+" 日空："+eightCharQuery.getDayXunKong()+"）");
            resultData.setNaYin("纳音："+eightCharQuery.getYearNaYin()+" "+eightCharQuery.getMonthNaYin()+" "+eightCharQuery.getDayNaYin()+" "+eightCharQuery.getTimeNaYin());
            resultData.setXingXiu("星宿："+lunarQuery.getXiu() + "宿" + RelationMapConstant.XING_XIU_FANG_WEI.get(lunarQuery.getXiu()));
            resultData.setHeiHuangDao("十二黑黄道："+RelationMapConstant.YUEDING_HEIHUANGDAO_MAP.get(eightCharQuery.getMonthZhi()+eightCharQuery.getDayZhi()));
            resultData.setWuBuYuShi(RelationMapConstant.WUBUYUSHI_MAP.containsKey(eightCharQuery.getDayGan()+"_"+eightCharQuery.getTime())?"五不遇时："+eightCharQuery.getDayGan()+"日"+eightCharQuery.getTime():"");
            resultData.setTianXianShiGe(RelationMapConstant.TIANXIANSHIGE_MAP.containsKey(eightCharQuery.getDayGan()+"_"+eightCharQuery.getTime())?"天显时格："+eightCharQuery.getDayGan()+"日"+eightCharQuery.getTime():"");
            resultData.setXiShenFang("喜神方："+RelationMapConstant.XISHENFANG_MAP.get(eightCharQuery.getDayGan()));
            resultData.setYiJi("今日宜忌：宜："+lunarQuery.getDayYi().stream().map(String::valueOf).collect(Collectors.joining(","))+ " 忌："+lunarQuery.getDayJi().stream().map(String::valueOf).collect(Collectors.joining(",")));
            resultData.setYearInGanZhi(eightCharQuery.getYear());
            resultData.setYearInXunKong(eightCharQuery.getYearXunKong());
            resultData.setMonthInGanZhi(eightCharQuery.getMonth());
            resultData.setMonthInXunKong(eightCharQuery.getMonthXunKong());
            resultData.setDayInGanZhi(eightCharQuery.getDay());
            resultData.setDayInXunKong(eightCharQuery.getDayXunKong());
            resultData.setTimeInGanZhi(eightCharQuery.getTime());
            resultData.setTimeInXunKong(eightCharQuery.getTimeXunKong());
            return CommonResult.success(resultData);
        }catch(ParseException e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }catch(Exception e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }

    }

    /**
     * 设置占时八字信息
     *
     * @param lunar
     * @param nowEightCharResp
     */
    private void setEightCharInfo(Lunar lunar, NowEightCharResp nowEightCharResp) {
        EightChar eightChar = lunar.getEightChar();
        Solar solar = lunar.getSolar();
        nowEightCharResp.setSolarCalendarDate(solar.toYmdHms());
        nowEightCharResp.setLunarCalendarDate(lunar.toString());
        nowEightCharResp.setYearInGanZhi(eightChar.getYear());
        nowEightCharResp.setYearXunKong(eightChar.getYearXunKong());
        nowEightCharResp.setMonthInGanZhi(eightChar.getMonth());
        nowEightCharResp.setMonthXunKong(eightChar.getMonthXunKong());
        nowEightCharResp.setDayInGanZhi(eightChar.getDay());
        nowEightCharResp.setDayXunKong(eightChar.getDayXunKong());
        nowEightCharResp.setTimeInGanZhi(eightChar.getTime());
        nowEightCharResp.setTimeXunKong(eightChar.getTimeXunKong());
    }

    /**
     * 设置八字信息
     *
     * @param eightChar
     * @param daYun
     * @param eightCharGanZhi
     */
    private void setEightCharItem(EightChar eightChar, DaYun daYun, EightCharGanZhi eightCharGanZhi) {
        LiuNian liuNian = daYun.getLiuNian()[0];
        eightCharGanZhi.setFleetingYearInGanZhi(liuNian.getGanZhi());
        eightCharGanZhi.setBigLuckInGanZhi(daYun.getGanZhi());
        eightCharGanZhi.setYearInGanZhi(eightChar.getYear());
        eightCharGanZhi.setMonthInGanZhi(eightChar.getMonth());
        eightCharGanZhi.setDayInGanZhi(eightChar.getDay());
        eightCharGanZhi.setTimeInGanZhi(eightChar.getTime());
    }


    /**
     * 格式化各个八字柱
     *
     * @param eightChar
     * @param yun
     * @param eightCharItemDTO
     */
    private void formatZhu(EightChar eightChar, Yun yun, EightCharItemDTO eightCharItemDTO) {
        // 获取性别
        Integer gender = yun.getGender();
        // 日柱天干
        String dayGan = eightChar.getDayGan();
        // 获取大运列表
        DaYun[] daYunList = yun.getDaYun();
        // 判断当前在那个大运上和流年上
        DaYun nowDaYun = null;
        LiuNian nowLiuNian = null;
        LiuNian[] nowLiuNianList = null;
        for (int i = 0; i < daYunList.length; i++) {
            // 判断是否开始大运了
            if (daYunList[0].getStartYear() > DateUtil.date().year()) {
                // 还没出生
                nowLiuNianList = daYunList[0].getLiuNian();
                break;
            }
            if (DateUtil.date().year() > daYunList[i].getStartYear() &&
                    DateUtil.date().year() < daYunList[i].getEndYear()) {
                nowLiuNianList = daYunList[i].getLiuNian();
                // 判断是否为第一个,不是大运
                if (i == 0) {
                    break;
                }
                // 当前年小于大运结束年份，说明在此大运上
                nowDaYun = daYunList[i];
                break;
            }
        }
        // 判断当前实在那个流年上
        if (nowLiuNianList != null) {
            for (LiuNian liuNian : nowLiuNianList) {
                // 判断出今年的流年
                if (liuNian.getYear() == DateUtil.date().year()) {
                    nowLiuNian = liuNian;
                }
            }
        }
        switch (eightCharItemDTO.getType()) {
            case LIUNIAN:
                if (nowLiuNian != null) {
                    eightCharItemDTO.setGanStr(nowLiuNian.getGanZhi().substring(0, 1));
                    eightCharItemDTO.setZhiStr(nowLiuNian.getGanZhi().substring(1, 2));
                }
                break;
            case DAYUN:
                if (nowDaYun != null) {
                    eightCharItemDTO.setGanStr(nowDaYun.getGanZhi().substring(0, 1));
                    eightCharItemDTO.setZhiStr(nowDaYun.getGanZhi().substring(1, 2));

                }
                break;
            case YEAR:
                eightCharItemDTO.setGanStr(eightChar.getYearGan());
                eightCharItemDTO.setZhiStr(eightChar.getYearZhi());
                break;
            case MONTH:
                eightCharItemDTO.setGanStr(eightChar.getMonthGan());
                eightCharItemDTO.setZhiStr(eightChar.getMonthZhi());
                break;
            case DAY:
                eightCharItemDTO.setGanStr(eightChar.getDayGan());
                eightCharItemDTO.setZhiStr(eightChar.getDayZhi());
                break;
            case TIME:
                eightCharItemDTO.setGanStr(eightChar.getTimeGan());
                eightCharItemDTO.setZhiStr(eightChar.getTimeZhi());
                break;
            default:
                break;
        }
        if (StringUtils.isEmpty(eightCharItemDTO.getGanStr()) || StringUtils.isEmpty(eightCharItemDTO.getZhiStr())) {
            return;
        }
        eightCharItemDTO.setGanWxColor(FulInitialsBeloEnum.getValueByelEment("天干", eightCharItemDTO.getGanStr()).getFiveElementsColor());
        eightCharItemDTO.setGanYyColor(FulInitialsBeloEnum.getValueByelEment("天干", eightCharItemDTO.getGanStr()).getYinYangColor());
        eightCharItemDTO.setZhiWxColor(FulInitialsBeloEnum.getValueByelEment("地支", eightCharItemDTO.getZhiStr()).getFiveElementsColor());
        eightCharItemDTO.setZhiYyColor(FulInitialsBeloEnum.getValueByelEment("地支", eightCharItemDTO.getZhiStr()).getYinYangColor());
        eightCharItemDTO.setGanShiShen(RelationMapConstant.TIANGAN_TIANGANSHISHEN_MAP.get(dayGan + eightCharItemDTO.getGanStr()));
        if (eightCharItemDTO.getType() == EightCharItemEnum.DAY) {
            if (gender.equals(GenderTypeEnum.MALE.getCode())) {
                eightCharItemDTO.setGanShiShen("元男");
            } else {
                eightCharItemDTO.setGanShiShen("元女");
            }

        }
        eightCharItemDTO.setGanZhiShiShen(RelationMapConstant.TIANGAN_DIZHISHISHEN_MAP.get(dayGan + eightCharItemDTO.getZhiStr()));
        // 获取藏干列表
        List<String> cangGanList = RelationMapConstant.DIZHI_CANGGAN.get(eightCharItemDTO.getZhiStr());
        List<CangGanDto> cangGanDtoList = new ArrayList<>(cangGanList.size());
        List<CangGanShiShenDto> cangGanShiShenDtoList = new ArrayList<>(cangGanList.size());
        cangGanList.forEach(item -> {
            CangGanDto cangGanDto = new CangGanDto();
            cangGanDto.setGanStr(item);
            cangGanDto.setGanWxColor(FulInitialsBeloEnum.getValueByelEment("天干", item).getFiveElementsColor());
            cangGanDto.setGanYyColor(FulInitialsBeloEnum.getValueByelEment("天干", item).getYinYangColor());
            cangGanDtoList.add(cangGanDto);
            CangGanShiShenDto cangGanShiShenDto = new CangGanShiShenDto();
            cangGanShiShenDto.setShiShen(RelationMapConstant.TIANGAN_TIANGANSHISHEN_MAP.get(dayGan + item));
            cangGanShiShenDto.setShiShenSimpleName(FulInitialsBeloEnum.getValueByelEment("十神",
                    cangGanShiShenDto.getShiShen()).getAbbreviation());
            cangGanShiShenDtoList.add(cangGanShiShenDto);
        });
        eightCharItemDTO.setCangGanList(cangGanDtoList);
        eightCharItemDTO.setCangGanShiShenList(cangGanShiShenDtoList);
        eightCharItemDTO.setXingYun(RelationMapConstant.TIANGAN_SHIERCHANGSHENG_MAP.get(dayGan + eightCharItemDTO.getZhiStr()));
        eightCharItemDTO.setZiZuo(RelationMapConstant.TIANGAN_SHIERCHANGSHENG_MAP.get(eightCharItemDTO.getGanStr() + eightCharItemDTO.getZhiStr()));
        eightCharItemDTO.setXunKong(RelationMapConstant.JIAZI_XUNKONG_MAP.get(eightCharItemDTO.getGanStr() + eightCharItemDTO.getZhiStr()));
        eightCharItemDTO.setNaYin(RelationMapConstant.JIAZI_NAYIN_MAP.get(eightCharItemDTO.getGanStr() + eightCharItemDTO.getZhiStr()));
    }

    /**
     * 根据八字获取司命
     *
     * @param lunar
     * @return {@link String}
     * @author zhangzedi
     * @date 2023/8/11 00:38
     */
    private String getSiMingByEightChar(Lunar lunar) {
        // 获取八字
        EightChar eightChar = lunar.getEightChar();
        // 获取上一个节令
        JieQi prevJie = lunar.getPrevJie(false);
        // 求出相隔分钟数
        int subtract = lunar.getSolar().subtractMinute(prevJie.getSolar());
        // 一天的分钟数
        int dayOfMinute = 24 * 60;
        // 转换为天数,带小数
        double subtractDay = (double) subtract / dayOfMinute;
        String siMing = "";
        String monthZhi = eightChar.getMonthZhi();
        switch (monthZhi) {
            case "子":
                if (subtractDay < 10.5) {
                    siMing = "壬";
                } else {
                    siMing = "癸";
                }
                break;
            case "丑":
                if (subtractDay < 9.3) {
                    siMing = "壬";
                } else if (subtractDay < 12.4) {
                    siMing = "辛";
                } else {
                    siMing = "己";
                }
                break;
            case "寅":
                if (subtractDay < 7.25) {
                    siMing = "戊";
                } else if (subtractDay < 14.5) {
                    siMing = "丙";
                } else {
                    siMing = "甲";
                }
                break;
            case "卯":
                if (subtractDay < 10.55) {
                    siMing = "甲";
                } else {
                    siMing = "乙";
                }
                break;
            case "辰":
                if (subtractDay < 9.3) {
                    siMing = "乙";
                } else if (subtractDay < 12.4) {
                    siMing = "癸";
                } else {
                    siMing = "戊";
                }
                break;
            case "巳":
                if (subtractDay < 5.15) {
                    siMing = "戊";
                } else if (subtractDay < 14.45) {
                    siMing = "庚";
                } else {
                    siMing = "丙";
                }
                break;
            case "午":
                if (subtractDay < 10.35) {
                    siMing = "丙";
                } else if (subtractDay < 20.7) {
                    siMing = "己";
                } else {
                    siMing = "丁";
                }
                break;
            case "未":
                if (subtractDay < 9.3) {
                    siMing = "丁";
                } else if (subtractDay < 12.5) {
                    siMing = "乙";
                } else {
                    siMing = "己";
                }
                break;
            case "申":
                if (subtractDay < 7.15) {
                    siMing = "己";
                } else if (subtractDay < 10.3) {
                    siMing = "戊";
                } else if (subtractDay < 13.45) {
                    siMing = "壬";
                } else {
                    siMing = "庚";
                }
                break;
            case "酉":
                if (subtractDay < 10.55) {
                    siMing = "庚";
                } else {
                    siMing = "辛";
                }
                break;
            case "戌":
                if (subtractDay < 9.3) {
                    siMing = "辛";
                } else if (subtractDay < 12.5) {
                    siMing = "丁";
                } else {
                    siMing = "戊";
                }
                break;
            case "亥":
                if (subtractDay < 7.25) {
                    siMing = "戊";
                } else if (subtractDay < 12.3) {
                    siMing = "甲";
                } else {
                    siMing = "壬";
                }
                break;
            default:
                break;
        }
        return siMing;
    }

    /**
     * 根据出生日期计算命卦
     *
     * @param lunar
     * @return
     */
    private String getMingGuaByBirth(Lunar lunar, Integer gender) {
        // 获取八字
        EightChar eightChar = lunar.getEightChar();
        // 获取出生阳历年
        Solar solar = lunar.getSolar();
        int year = solar.getYear();
        // 取余数
        int yearBirth = year % 100;
        int yushu;
        String genderStr;
        if (year < 2000) {
            // 1900开头
            if (GenderTypeEnum.MALE.getCode().equals(gender)) {
                // 男性
                yushu = (100 - yearBirth) % 9;
                genderStr = GenderTypeEnum.MALE.getInfo();
            } else {
                yushu = Math.abs((yearBirth - 4) % 9);
                genderStr = GenderTypeEnum.FEMALE.getInfo();

            }
        } else {
            // 2000开头
            if (GenderTypeEnum.MALE.getCode().equals(gender)) {
                // 男性
                yushu = (99 - yearBirth) % 9;
                genderStr = GenderTypeEnum.MALE.getInfo();
            } else {
                yushu = (yearBirth + 6) % 9;
                genderStr = GenderTypeEnum.FEMALE.getInfo();
            }
        }
        // 获取命卦
        String mingGua = RelationMapConstant.MING_GUA_MAP.get(genderStr + yushu);
        return mingGua + "（" + RelationMapConstant.MING_GUA_FANG_WEI.get(mingGua) + "）";
    }

    /**
     * 纳音加上括号
     *
     * @param jiazi
     * @return
     */
    private String formatNaYinChar(String jiazi) {
        return "（" + RelationMapConstant.JIAZI_NAYIN_MAP.get(jiazi) + "）";
    }
}
